﻿using HalconDotNet;
using IniReadWrite;
using MvCamCtrl.NET.CameraParams;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using VisionRoc.Tool;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace VisionRoc.Core
{

    public class GenericModelMatch
    {  /// </summary>
       /// 模版参数完整路径
       /// </summary>
        public string m_Path;

        /// <summary>
        /// 模版句柄路径
        /// </summary>
        string ModelIDPath;

        string ModelIDBasePath;

        public GenericModelMatch(string _Path)
        {
            HOperatorSet.GenEmptyObj(out ImageReduce);
            HOperatorSet.GenEmptyObj(out ModelContour);
            HOperatorSet.GenEmptyObj(out ModelRegion);
            HOperatorSet.GenEmptyObj(out Cross);
            HOperatorSet.GenEmptyObj(out SearchRegioin);
            //判断文件路径是否存在
            if (!Directory.Exists(_Path))
            {
                Directory.CreateDirectory(_Path);
            }
            m_Path = _Path + "\\Match.ini";
            //判断文件是否存在
            if (File.Exists(m_Path))
            {
                ReadMatchParameter();
            }
            ModelIDPath = _Path + "\\ModelID.shm";
            ModelIDBasePath = _Path + "\\ModelIDBase.tup";
            //判断文件是否存在
            if (File.Exists(ModelIDPath))
            {
                ReadShapeModel();
            }
            if (File.Exists(ModelIDBasePath))
            {
                HOperatorSet.ReadTuple(ModelIDBasePath, out HomMat2DBase);
            }
        }

        #region 参数设置

        [Category("0模板信息"), DisplayName("1模板名称"), Browsable(true), ReadOnly(false)]
        public string ModelName { get; set; } = "模板名称";


        [Category("1模板生成参数"), DisplayName("01模板最小对比度"), Description("定义模板图像中边缘的最低对比度阈值,低于此值的边缘将被忽略。\r\n值过低：保留更多弱边缘，可能引入噪声。\r\n值过高：丢失关键细节，导致模型匹配能力下降。"), Browsable(true), ReadOnly(false)]
        public int ContrastLow { get; set; } = 20;


        [Category("1模板生成参数"), DisplayName("02模板最大对比度"), Description("定义模板图像中边缘的最高对比度阈值，高于此值的边缘将被视为强边缘并优先保留。\r\n值过低：强边缘被截断，模型鲁棒性降低。\r\n值过高：所有边缘被保留，可能包含冗余信息。"), Browsable(true), ReadOnly(false)]
        public int ContrastHigh { get; set; } = 50;


        [Category("1模板生成参数"), DisplayName("03最小缩放比率"), Description("同步缩放默认值为0.9如果等于1就没有缩放比率,\r\n若允许缩小到原图50%,则设为 0.5"), Browsable(true), ReadOnly(false)]
        public double ScaleMin { get; set; } = 1;


        [Category("1模板生成参数"), DisplayName("04最大缩放比率"), Description("同步缩放默认值为1.1如果等于1就没有缩放比率,\r\n若允许放大到200%,则设为2.0"), Browsable(true), ReadOnly(false)]
        public double ScaleMax { get; set; } = 1;

        [XmlElement("ScaleRowMin")]
        [Category("1模板生成参数"), DisplayName("05最小行方向缩放比率"), Description("异步缩放最小行方向缩放比率,等于1没有缩放"), Browsable(true), ReadOnly(false)]
        public double ScaleRowMin { get; set; } = 1;


        [Category("1模板生成参数"), DisplayName("06最大行方向缩放比率"), Description("异步缩放最大行方向缩放比率,等于1没有缩放"), Browsable(true), ReadOnly(false)]
        public double ScaleRowMax { get; set; } = 1;


        [Category("1模板生成参数"), DisplayName("07最小列方向缩放比率"), Description("异步缩放最小列方向缩放比率,等于1没有缩放"), Browsable(true), ReadOnly(false)]
        public double ScaleColMin { get; set; } = 1;


        [Category("1模板生成参数"), DisplayName("08最大列方向缩放比率"), Description("异步缩放最大列方向缩放比率,等于1没有缩放"), Browsable(true), ReadOnly(false)]
        public double ScaleColMax { get; set; } = 1;


        [Category("2模板运行参数"), DisplayName("09最大匹配数量"), Description("最大匹配数,设为0返回所有匹配"), Browsable(true), ReadOnly(false)]
        public int NumMatches { get; set; } = 1;


        [Category("2模板运行参数"), DisplayName("10模板最小匹配分数"), Description("值越高匹配越严格,但可能漏检。建议从0.7开始调整。"), Browsable(true), ReadOnly(false)]
        public double MinScore { get; set; } = 0.5;


        [Category("2模板运行参数"), DisplayName("11模板角度范围起点"), Description("若已知目标角度范围,缩小此范围可加快搜索,最小值-180。"), Browsable(true), ReadOnly(false)]
        public double ModelAngleStart { get; set; } = -90;


        [Category("2模板运行参数"), DisplayName("12模板角度范围终点"), Description("模板搜索角度范围 最大值180"), Browsable(true), ReadOnly(false)]
        public double ModelAngleEnd { get; set; } = 90;


        [Category("2模板运行参数"), DisplayName("13最大重叠率"), Description("抑制重叠的匹配结果,值越小越严格。"), Browsable(true), ReadOnly(false)]
        public double MaxOverlap { get; set; } = 0.5;


        [Category("3显示信息"), DisplayName("1显示模版"), Description("显示模版轮廓"), Browsable(true), ReadOnly(false)]
        public bool DisplayShape { get; set; } = false;


        [Category("3显示信息"), DisplayName("2显示区域"), Description("显示搜索模版区域"), Browsable(true), ReadOnly(false)]
        public bool DisplaySearch { get; set; } = false;


        [Category("3显示信息"), DisplayName("3显示位置"), Description("显示模版中心坐标"), Browsable(true), ReadOnly(false)]
        public bool DisplayLoction { get; set; } = false;


        [Category("4搜索框坐标"), DisplayName("1搜索框坐标Row1"), Browsable(true), ReadOnly(true)]
        public double SearchRegionRow1 { get; set; }


        [Category("4搜索框坐标"), DisplayName("2搜索框坐标Col1"), Browsable(true), ReadOnly(true)]
        public double SearchRegionCol1 { get; set; }


        [Category("4搜索框坐标"), DisplayName("3搜索框坐标Row1"), Browsable(true), ReadOnly(true)]
        public double SearchRegionRow2 { get; set; }


        [Category("4搜索框坐标"), DisplayName("4搜索框坐标Col2"), Browsable(true), ReadOnly(true)]
        public double SearchRegionCol2 { get; set; }


        [Category("5模板基准点"), DisplayName("1模板基准点Row"), Browsable(true), ReadOnly(true)]
        public double CreateRow { get; set; }


        [Category("5模板基准点"), DisplayName("2模板基准点Col"), Browsable(true), ReadOnly(true)]
        public double CreateCol { get; set; }


        [Category("5模板基准点"), DisplayName("3模板基准点Angle"), Browsable(true), ReadOnly(true)]
        public double CreateAngle { get; set; }

        public HTuple HomMat2DModel = new HTuple();

        /// <summary>
        /// 创建模版矩阵
        /// </summary>
        public HTuple HomMat2DBase = new HTuple();

        public HTuple ModelID = new HTuple();

        #endregion

        HObject ImageReduce;

        /// <summary>
        /// 模版轮廓
        /// </summary>
        HObject ModelContour;

        /// <summary>
        /// 模版查找结果
        /// </summary>
        HTuple NumMatchResult = new HTuple();

        HTuple hv_MatchResultID = new HTuple();

        /// <summary>
        /// 是否找到模版 1：OK 2：NG
        /// </summary>
        public int IsFindModel;

        /// <summary>
        /// 实时搜索框区域
        /// </summary>
        HObject SearchRegioin;

        /// 模板坐标十字叉
        /// </summary>
        HObject Cross;

        /// <summary>
        /// 模版创建区域
        /// </summary>
        public HObject ModelRegion;

        /// <summary>
        /// 查找模版输出参数
        /// </summary>
        public HTuple Row = new HTuple(), Col = new HTuple(), Angle = new HTuple(), Score = new HTuple();

        /// <summary>
        /// 创建模版
        /// </summary>
        /// <param name="Image"></param>
        /// <param name="hWindow"></param>
        /// <param name="_ModelID"></param>
        public void Create_Generic_Shape_Model(HObject Image, HWindow hWindow, out HTuple _ModelID)
        {
            HOperatorSet.ReduceDomain(Image, ModelRegion, out HObject ImageReduced);
            HOperatorSet.CreateGenericShapeModel(out _ModelID);
            HOperatorSet.SetGenericShapeModelParam(_ModelID, "num_matches", NumMatches);
            HOperatorSet.SetGenericShapeModelParam(_ModelID, "metric", "use_polarity");
            HOperatorSet.SetGenericShapeModelParam(_ModelID, "angle_start", (new HTuple(ModelAngleStart)).TupleRad());
            HOperatorSet.SetGenericShapeModelParam(_ModelID, "angle_end", (new HTuple(ModelAngleEnd)).TupleRad());
            HOperatorSet.SetGenericShapeModelParam(_ModelID, "min_score", MinScore);
            HOperatorSet.SetGenericShapeModelParam(_ModelID, "num_levels", 0);
            HOperatorSet.SetGenericShapeModelParam(_ModelID, "greediness", 0.0);
            HOperatorSet.SetGenericShapeModelParam(_ModelID, "subpixel", "least_squares_very_high");
            if (ContrastLow > 0)
            {
                if (ContrastHigh >= ContrastLow)
                {
                    HOperatorSet.SetGenericShapeModelParam(_ModelID, "contrast_low", ContrastLow);
                    HOperatorSet.SetGenericShapeModelParam(_ModelID, "contrast_high", ContrastHigh);
                }
            }
            //高级参数
            HOperatorSet.SetGenericShapeModelParam(_ModelID, "max_overlap", MaxOverlap);
            //同步缩放
            if (ScaleMin != 1)
            {
                HOperatorSet.SetGenericShapeModelParam(_ModelID, "iso_scale_min", ScaleMin);
            }
            if (ScaleMax != 1)
            {
                HOperatorSet.SetGenericShapeModelParam(_ModelID, "iso_scale_max", ScaleMax);
            }
            //异步缩放
            if (ScaleRowMin != 1)
            {
                HOperatorSet.SetGenericShapeModelParam(_ModelID, "scale_row_min", ScaleMin);
            }
            if (ScaleRowMax != 1)
            {
                HOperatorSet.SetGenericShapeModelParam(ModelID, "scale_row_max", ScaleMax);
            }
            if (ScaleColMin != 1)
            {
                HOperatorSet.SetGenericShapeModelParam(_ModelID, "scale_column_min", ScaleMin);
            }
            if (ScaleColMax != 1)
            {
                HOperatorSet.SetGenericShapeModelParam(_ModelID, "scale_column_max", ScaleMax);
            }
            //训练模板
            HOperatorSet.TrainGenericShapeModel(ImageReduced, _ModelID);
            ModelID = _ModelID;
            if (ModelID.Length > 0)
            {
                if (SearchRegionRow1 > 0 && SearchRegionRow2 > 0)
                {
                    SearchRegioin.Dispose();
                    HOperatorSet.GenRectangle1(out SearchRegioin, SearchRegionRow1, SearchRegionCol1, SearchRegionRow2, SearchRegionCol2);
                    ImageReduce.Dispose();
                    HOperatorSet.ReduceDomain(Image, SearchRegioin, out ImageReduce);
                    HOperatorSet.SetGenericShapeModelParam(ModelID, "angle_start", (new HTuple(ModelAngleStart)).TupleRad());
                    HOperatorSet.SetGenericShapeModelParam(ModelID, "angle_end", (new HTuple(ModelAngleEnd)).TupleRad());
                    HOperatorSet.SetGenericShapeModelParam(ModelID, "min_score", MinScore);
                    HOperatorSet.SetGenericShapeModelParam(ModelID, "num_matches", NumMatches);
                    HOperatorSet.SetGenericShapeModelParam(ModelID, "max_overlap", MaxOverlap);
                    NumMatchResult.Dispose(); hv_MatchResultID.Dispose();
                    HOperatorSet.FindGenericShapeModel(ImageReduce, ModelID, out hv_MatchResultID, out NumMatchResult);
                }
                else
                {
                    HOperatorSet.SetGenericShapeModelParam(ModelID, "angle_start", (new HTuple(ModelAngleStart)).TupleRad());
                    HOperatorSet.SetGenericShapeModelParam(ModelID, "angle_end", (new HTuple(ModelAngleEnd)).TupleRad());
                    HOperatorSet.SetGenericShapeModelParam(ModelID, "min_score", MinScore);
                    HOperatorSet.SetGenericShapeModelParam(ModelID, "num_matches", NumMatches);
                    HOperatorSet.SetGenericShapeModelParam(ModelID, "max_overlap", MaxOverlap);
                    NumMatchResult.Dispose(); hv_MatchResultID.Dispose();
                    HOperatorSet.FindGenericShapeModel(Image, ModelID, out hv_MatchResultID, out NumMatchResult);
                }
                if (NumMatchResult.I == 0)
                {
                    IsFindModel = 2;
                    NumMatchResult = 0;
                    Row = 0;
                    Col = 0;
                    Angle = 0;
                    Score = 0;
                    MyHOperatorSet.DispMeassge(hWindow, "未找到模版", "window", "center", "center", 20, "red");
                    return;
                }
                else
                {
                    HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, "best", "row", out HTuple hv_Row);
                    HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, "best", "column", out HTuple hv_Column);
                    HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, "best", "angle", out HTuple hv_Angle);
                    HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, "best", "score", out HTuple hv_Score);
                    HomMat2DBase.Dispose();
                    HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, "best", "hom_mat_2d", out HomMat2DBase);
                    HOperatorSet.WriteTuple(HomMat2DBase, ModelIDBasePath);
                    if (DisplayShape)
                    {
                        ModelContour.Dispose();
                        HOperatorSet.GetGenericShapeModelResultObject(out ModelContour, hv_MatchResultID, "all", "contours");
                        HOperatorSet.SetColor(hWindow, "green");
                        HOperatorSet.DispObj(ModelContour, hWindow);
                    }
                    // 判断是否显示位置坐标
                    if (DisplayLoction)
                    {
                        for (int i = 0; i < Score.Length; i++)
                        {
                            Cross.Dispose();
                            HOperatorSet.GenCrossContourXld(out Cross, Row[i], Col[i], 100, Angle[i]);
                            HOperatorSet.SetColor(hWindow, "red");
                            HOperatorSet.DispObj(Cross, hWindow);
                        }
                    }
                    //判断是否显示搜索区域
                    if (DisplaySearch)
                    {
                        //判断区域坐标是否有值
                        if (SearchRegionRow1 > 0 && SearchRegionRow2 > 0)
                        {
                            MyHOperatorSet.DispContour(hWindow, Model.margin, "blue", SearchRegioin);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 查找模版
        /// </summary>
        /// <param name="Image"></param>
        /// <param name="hWindow"></param>
        public void Find_Generic_Shape_Model(HObject Image, HWindow hWindow, out HTuple _HomMat2D)
        {
            _HomMat2D = null;
            try
            {
                IsFindModel = 0;
                HOperatorSet.CountObj(Image, out HTuple tuple1);
                if (tuple1.I == 0)
                {
                    MyHOperatorSet.DispMeassge(hWindow, "图像为空！", "window", "center", "center", 20, "red");
                    return;
                }
                if (ModelID.Length > 0)
                {
                    //判断区域搜索还是全图搜索
                    if (SearchRegionRow1 > 0 && SearchRegionRow2 > 0)
                    {
                        SearchRegioin.Dispose();
                        HOperatorSet.GenRectangle1(out SearchRegioin, SearchRegionRow1, SearchRegionCol1, SearchRegionRow2, SearchRegionCol2);
                        ImageReduce.Dispose();
                        HOperatorSet.ReduceDomain(Image, SearchRegioin, out ImageReduce);
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "angle_start", (new HTuple(ModelAngleStart)).TupleRad());
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "angle_end", (new HTuple(ModelAngleEnd)).TupleRad());
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "min_score", MinScore);
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "num_matches", NumMatches);
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "max_overlap", MaxOverlap);
                        NumMatchResult.Dispose(); hv_MatchResultID.Dispose();
                        HOperatorSet.FindGenericShapeModel(ImageReduce, ModelID, out hv_MatchResultID, out NumMatchResult);
                    }
                    else
                    {
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "angle_start", (new HTuple(ModelAngleStart)).TupleRad());
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "angle_end", (new HTuple(ModelAngleEnd)).TupleRad());
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "min_score", MinScore);
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "num_matches", NumMatches);
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "max_overlap", MaxOverlap);
                        NumMatchResult.Dispose(); hv_MatchResultID.Dispose();
                        HOperatorSet.FindGenericShapeModel(Image, ModelID, out hv_MatchResultID, out NumMatchResult);
                    }
                    if (NumMatchResult.I == 0)
                    {
                        IsFindModel = 2;
                        NumMatchResult = 0;
                        Row = 0;
                        Col = 0;
                        Angle = 0;
                        Score = 0;
                        MyHOperatorSet.DispMeassge(hWindow, "未找到模版", "window", "center", "center", 20, "red");
                        return;
                    }
                    else
                    {
                        IsFindModel = 1;
                        for (int i = 0; i < NumMatchResult; i++)
                        {
                            HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, i, "row", out HTuple hv_Row);
                            HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, i, "column", out HTuple hv_Column);
                            HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, i, "angle", out HTuple hv_Angle);
                            HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, i, "score", out HTuple hv_Score);
                            HomMat2DModel.Dispose();
                            HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, "best", "hom_mat_2d", out HomMat2DModel);
                            HOperatorSet.HomMat2dInvert(HomMat2DBase, out HTuple homMat2DInvert);
                            HOperatorSet.HomMat2dCompose(HomMat2DModel, homMat2DInvert, out _HomMat2D);
                            //把角度转为弧度
                            HOperatorSet.TupleDeg(hv_Angle, out hv_Angle);
                            Score[i] = hv_Score;
                            Row[i] = hv_Row;
                            Col[i] = hv_Column;
                            Angle[i] = hv_Angle;
                        }
                        if (DisplayShape)
                        {
                            ModelContour.Dispose();
                            HOperatorSet.GetGenericShapeModelResultObject(out ModelContour, hv_MatchResultID, "all", "contours");
                            HOperatorSet.SetColor(hWindow, "green");
                            HOperatorSet.DispObj(ModelContour, hWindow);
                        }
                        // 判断是否显示位置坐标
                        if (DisplayLoction)
                        {
                            for (int i = 0; i < Score.Length; i++)
                            {
                                Cross.Dispose();
                                HOperatorSet.GenCrossContourXld(out Cross, Row[i], Col[i], 100, Angle[i]);
                                HOperatorSet.SetColor(hWindow, "red");
                                HOperatorSet.DispObj(Cross, hWindow);
                            }
                        }
                        //判断是否显示搜索区域
                        if (DisplaySearch)
                        {
                            //判断区域坐标是否有值
                            if (SearchRegionRow1 > 0 && SearchRegionRow2 > 0)
                            {
                                MyHOperatorSet.DispContour(hWindow, Model.margin, "blue", SearchRegioin);
                            }
                        }
                    }
                }
                else
                {
                    MyHOperatorSet.DispMeassge(hWindow, "模版句柄为空", "window", "center", "center", 20, "red");
                    return;
                }
            }
            catch (Exception ex)
            {
                IsFindModel = 2;
                MyHOperatorSet.DispMeassge(hWindow, "查找模版异常", "window", "center", "center", 20, "red");
                TxtAPI.WriteLogTxt($"模版查找异常,异常信息：{ex.ToString()}");
                return;
            }
        }

        /// <summary>
        /// 保存模板参数
        /// </summary>
        public void WriteMatchParameter()
        {
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "ModelName", ModelName.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "ContrastLow", ContrastLow.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "ContrastHigh", ContrastHigh.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "ScaleMin", ScaleMin.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "ScaleMax", ScaleMax.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "ScaleRowMin", ScaleRowMin.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "ScaleRowMax", ScaleRowMax.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "ScaleColMin", ScaleColMin.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "ScaleColMax", ScaleColMax.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "NumMatches", NumMatches.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "MinScore", MinScore.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "ModelAngleStart", ModelAngleStart.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "ModelAngleEnd", ModelAngleEnd.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "MaxOverlap", MaxOverlap.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "DisplayShape", DisplayShape.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "DisplaySearch", DisplaySearch.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "DisplayLoction", DisplayLoction.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "SearchRegionRow1", SearchRegionRow1.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "SearchRegionCol1", SearchRegionCol1.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "SearchRegionRow2", SearchRegionRow2.ToString());
            IniAPI.INIWriteValue(m_Path, "ModelInfo", "SearchRegionCol2", SearchRegionCol2.ToString());

        }

        /// <summary>
        /// 读取模板参数
        /// </summary>
        public void ReadMatchParameter()
        {
            try
            {
                ModelName = IniAPI.INIGetStringValue(m_Path, "ModelInfo", "ModelName", "模版名称");
                ContrastLow = Convert.ToInt32(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "ContrastLow", "10"));
                ContrastHigh = Convert.ToInt32(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "ContrastHigh", "50"));
                ScaleMin = Convert.ToInt32(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "ScaleMin", "1"));
                ScaleMax = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "ScaleMax", "1"));
                ScaleRowMin = Convert.ToInt32(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "ScaleRowMin", "1"));
                ScaleRowMax = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "ScaleRowMax", "1"));
                ScaleColMin = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "ScaleColMin", "1"));
                ScaleColMax = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "ScaleColMax", "1"));
                NumMatches = Convert.ToInt32(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "NumMatches", "1"));
                MinScore = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "MinScore", "0.5"));
                ModelAngleStart = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "ModelAngleStart", "-90"));
                ModelAngleEnd = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "ModelAngleEnd", "90"));
                MaxOverlap = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "MaxOverlap", "0.5"));
                DisplayShape = Convert.ToBoolean(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "DisplayShape", "false"));
                DisplaySearch = Convert.ToBoolean(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "DisplaySearch", "false"));
                DisplayLoction = Convert.ToBoolean(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "DisplayLoction", "false"));
                SearchRegionRow1 = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "SearchRegionRow1", "0"));
                SearchRegionCol1 = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "SearchRegionCol1", "0"));
                SearchRegionRow2 = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "SearchRegionRow2", "0"));
                SearchRegionCol2 = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "SearchRegionCol2", "0"));
                CreateRow = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "CreateRow", "0"));
                CreateCol = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "CreateCol", "0"));
                CreateAngle = Convert.ToDouble(IniAPI.INIGetStringValue(m_Path, "ModelInfo", "CreateAngle", "0"));
            }
            catch { }

        }

        /// <summary>
        /// 保存模板
        /// </summary>
        public bool WriteShapelModel()
        {
            HOperatorSet.WriteShapeModel(ModelID, ModelIDPath);
            if (File.Exists(ModelIDPath))
            {
                //判断如果有这个文件则保存成功
                return true;
            }
            return false;
        }

        /// <summary>
        /// 读取模板 
        /// </summary>
        public bool ReadShapeModel()
        {
            if (File.Exists(ModelIDPath))
            {
                //判断如果有模板句柄这个文件 就读取
                HOperatorSet.ReadShapeModel(ModelIDPath, out ModelID);
                //HOperatorSet.ReadShapeModel(ModelIDBasePath, out HomMat2DBase);
                if (ModelID.Length > 0)
                {
                    return true;
                }
                return false;
            }
            return false;
        }

        /// <summary>
        /// 基准点设置
        /// </summary>
        public bool DatumPointSet(HObject Image, HWindow hWindow)
        {
            try
            {
                if (ModelID.Length > 0)
                {
                    if (SearchRegionRow1 > 0 && SearchRegionRow2 > 0)
                    {
                        SearchRegioin.Dispose();
                        HOperatorSet.GenRectangle1(out SearchRegioin, SearchRegionRow1, SearchRegionCol1, SearchRegionRow2, SearchRegionCol2);
                        ImageReduce.Dispose();
                        HOperatorSet.ReduceDomain(Image, SearchRegioin, out ImageReduce);
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "angle_start", (new HTuple(ModelAngleStart)).TupleRad());
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "angle_end", (new HTuple(ModelAngleEnd)).TupleRad());
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "min_score", MinScore);
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "num_matches", NumMatches);
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "max_overlap", MaxOverlap);
                        NumMatchResult.Dispose(); hv_MatchResultID.Dispose();
                        HOperatorSet.FindGenericShapeModel(ImageReduce, ModelID, out hv_MatchResultID, out NumMatchResult);
                    }
                    else
                    {
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "angle_start", (new HTuple(ModelAngleStart)).TupleRad());
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "angle_end", (new HTuple(ModelAngleEnd)).TupleRad());
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "min_score", MinScore);
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "num_matches", NumMatches);
                        HOperatorSet.SetGenericShapeModelParam(ModelID, "max_overlap", MaxOverlap);
                        NumMatchResult.Dispose(); hv_MatchResultID.Dispose();
                        HOperatorSet.FindGenericShapeModel(Image, ModelID, out hv_MatchResultID, out NumMatchResult);
                    }
                    if (NumMatchResult.I == 0)
                    {
                        IsFindModel = 2;
                        NumMatchResult = 0;
                        Row = 0;
                        Col = 0;
                        Angle = 0;
                        Score = 0;
                        MyHOperatorSet.DispMeassge(hWindow, "未找到模版", "window", "center", "center", 20, "red");
                        return false;
                    }
                    else
                    {
                        HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, "best", "row", out HTuple hv_Row);
                        HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, "best", "column", out HTuple hv_Column);
                        HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, "best", "angle", out HTuple hv_Angle);
                        HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, "best", "score", out HTuple hv_Score);
                        HomMat2DBase.Dispose();
                        HOperatorSet.GetGenericShapeModelResult(hv_MatchResultID, "best", "hom_mat_2d", out HomMat2DBase);
                        HOperatorSet.WriteTuple(HomMat2DBase, ModelIDBasePath);

                        if (DisplayShape)
                        {
                            ModelContour.Dispose();
                            HOperatorSet.GetGenericShapeModelResultObject(out ModelContour, hv_MatchResultID, "all", "contours");
                            HOperatorSet.SetColor(hWindow, "green");
                            HOperatorSet.DispObj(ModelContour, hWindow);
                        }
                        // 判断是否显示位置坐标
                        if (DisplayLoction)
                        {
                            for (int i = 0; i < Score.Length; i++)
                            {
                                Cross.Dispose();
                                HOperatorSet.GenCrossContourXld(out Cross, Row[i], Col[i], 100, Angle[i]);
                                HOperatorSet.SetColor(hWindow, "red");
                                HOperatorSet.DispObj(Cross, hWindow);
                            }
                        }
                        //判断是否显示搜索区域
                        if (DisplaySearch)
                        {
                            //判断区域坐标是否有值
                            if (SearchRegionRow1 > 0 && SearchRegionRow2 > 0)
                            {
                                MyHOperatorSet.DispContour(hWindow, Model.margin, "blue", SearchRegioin);
                            }
                        }

                        return true;
                    }
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                TxtAPI.WriteLogTxt($"模版基准设置失败:{ex.ToString()}");
                return false;
            }

        }

    }
}
